﻿<!-- © 2009 Zoltan Foley-Fisher ALL RIGHTS RESERVED -->

<html>

<head>
<title>Route Designer</title>


<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
	
<script type="text/javascript" src="jquery-1.3.2.js"></script>

<script type="text/javascript" src="trace.js"></script>

<script type="text/javascript" src="dataStructure.js"></script>
<script type="text/javascript" src="orienteering.js"></script>

<script type="text/javascript" src="control.js"></script>
	
<script type="text/javascript" src="canvas.js"></script>


<script type="text/javascript">


	
function exportAsPNG(event)
{
    var element = document.getElementById('canvas1');
    var strData = element.toDataURL("image/png");
	window.open(strData);
}

function loadData(event)
{
    deleteAll();
    decodeData($('#data').val());
    reset();
    
    markAllPointsAsNeedingRender();
    render();
}


function zoomAndPrint(event)
{
    zoomIn();
    window.print();
}

        
function zoomIn(event)
{
        $('#canvas1').height(HEIGHT);
        $('#canvas1').width(WIDTH);
}        
function zoomOut(event)
{
        var fraction = 300 / HEIGHT;
        $('#canvas1').height(300);
        $('#canvas1').width(fraction * WIDTH);
}


function loadBackgroundImage(event)
{
    var v = $('#imageLocation').val();  
    
    var img = new Image();  
    img.onload = function()
    {  
		canvasSetSize(img.width, img.height)
		
		canvasSetBackgroundImage(img);
		
        zoomOut();
		
        markAllPointsAsNeedingRender();
        render();
    }  
    img.src = v;
	
	trace("loadBackgroundImage from "+v);
    
}

// function setLineScale(event)
// {
//      
//     var v = parseFloat($('#lineScale').val()); 
//     
//         markAllPointsAsNeedingRender();
//         POINTRADIUS = 30 * v;
//         LINEWIDTH = 6 * v;
//         render();
//         
//  trace("setLineScale to "+v);
//     
// }


function setDrawingOperation(event)
{
    var value = $('input[name=group1]:checked').val() 
    
    setFunction(value);
}


	function main(event) {
				
		if (controlInitialise())
		{
				
			        trace("finished controlInitialise");
			if (canvasInitialise('canvas1'))
			{
			        trace("finished canvasInitialise");
			
			        setTargetForRender(C2D)
                    setDataCallback(function(s)
                    {
                        $('#data').val(s)
                    })
                    setResetCallback(function()
                    {
		                calculateSiteStylesAndIndexes(true)
                    })
                    
			        loadBackgroundImage();
			       // setLineScale();
			        setDrawingOperation();
			        loadData();
			        
			        //relaxC();
			        
			        
    				$('#error').hide();
			}
		}
		
	}

		
</script>


</head>



<!--http://www.attackpoint.org/discussionthread.jsp/message_4488-->
<!--[if IE]><script type="text/javascript"
src="/path/to/excanvas.js"></script><![endif]-->


<body onload="main(event)" onkeydown="keyFunctionChosen(event)">
	
	    
<div class="noprint">
	<h2 class="title">© 2006-2009 Zoltan Foley-Fisher</h2>
	<h1 class="title">Route Designer</h1>
	Route Designer is a point-and-click route design tool. Create and manipulate route waypoints and Route Designer will automatically apply labelling information. Suitable for sport course design.
</div>
	
	
<div class="noprint">
	<p id="error">
	Route Designer requires JavaScript and HTML Canvas provided by recent versions of <a href="http://www.apple.com/safari/">Safari</a>, <a href="http://www.mozilla.com/firefox/">Firefox</a>, <a href="http://www.google.com/chrome">Chrome</a> or <a href="http://www.opera.com/index.dml">Opera</a></p>
</div>

<div class="noprint">
<b>1. Choose a map image to import</b><br>Enter a URL to an image on the Internet or in a local file.<br>
<label>Image Location:<input type="text" id="imageLocation" value="QE.gif"/></label>
<input type="button" onclick="loadBackgroundImage(event)" value="Import"/>
<br>
<br>
</div>


<div class="noprint">
<!--
<label>Line Scale:<input type="text" id="lineScale" value="1"/></label>
<input type="button" onclick="setLineScale(event)" value="Set"/>
<br>
-->
</div>

<div class="noprint">
<b>2. Design a course</b><br>Use the following drawing operations to add control sites. Controls will be numbered and start and finish sites marked automatically.
<br>
<span  onclick="setDrawingOperation(event)">
    
    <!--
    <label>Site:<input id="functionSite" type="radio" name="group1" value="functionSite" checked="true"/></label>
    <label>Point:<input id="functionPoint" type="radio" name="group1" value="functionPoint"/></label>
    <label>Line:<input id="functionLine" type="radio" name="group1" value="functionLine"/></label>
    <label>Arc:<input id="functionArc" type="radio" name="group1" value="functionArc"/></label>
    <label>Text:<input id="functionText" type="radio" name="group1" value="functionText"/></label>
    <label>Move:<input id="functionMove" type="radio" name="group1" value="functionMove"/></label>
    <label>Delete:<input id="functionDelete" type="radio" name="group1" value="functionDelete"/></label>
    <label>Horizontal:<input id="functionHorizontal" type="radio" name="group1" value="functionHorizontal"/></label>
    <label>Vertical:<input id="functionVertical" type="radio" name="group1" value="functionVertical"/></label>
    <label>Length:<input id="functionLength" type="radio" name="group1" value="functionLength"/></label>
    
-->
    <label>Site:<input id="functionSite" type="radio" name="group1" value="functionSite" checked="true"/></label>
    <label>Line:<input id="functionLine" type="radio" name="group1" value="functionLine"/></label>
    <label>Move:<input id="functionMove" type="radio" name="group1" value="functionMove"/></label>
    <label>Delete:<input id="functionDelete" type="radio" name="group1" value="functionDelete"/></label>


</span>
<br>
Shortcuts: Hold down the control key and press the key for the first letter of the operation.
<br>

<input type="button" onclick="zoomIn(event)" value="Zoom In"/>
<input type="button" onclick="zoomOut(event)" value="Zoom Out"/>
<br>
</div>
	
<canvas id="canvas1" onmousedown="controlMouseDown(event)" onmousemove="controlMouseMove(event)" onmouseup="controlMouseUp(event)">
</canvas>

<br>
<br>


<div class="noprint">
<b>3. Save and Load</b><br>
Copy the text from the following box to a safe location to save, paste saved text into the box to load.<br>
<label>Diagram data:<input type="text" id="data" value="e[0]=new Object();e[0].type='VectorObject';e[0].v0='791';e[0].v1='1191';e[1]=new Object();e[1].type='Point';e[1].v0='0';e[2]=new Object();e[2].type='StringObject';e[2].v0='';e[3]=new Object();e[3].type='Text';e[3].v0='2';e[3].v1='1';e[4]=new Object();e[4].type='Site';e[4].v0='3';e[5]=new Object();e[5].type='VectorObject';e[5].v0='501';e[5].v1='700';e[6]=new Object();e[6].type='Point';e[6].v0='5';e[7]=new Object();e[7].type='StringObject';e[7].v0='1';e[8]=new Object();e[8].type='Text';e[8].v0='7';e[8].v1='6';e[9]=new Object();e[9].type='Site';e[9].v0='8';e[10]=new Object();e[10].type='VectorObject';e[10].v0='955';e[10].v1='335';e[11]=new Object();e[11].type='Point';e[11].v0='10';e[12]=new Object();e[12].type='StringObject';e[12].v0='2';e[13]=new Object();e[13].type='Text';e[13].v0='12';e[13].v1='11';e[14]=new Object();e[14].type='Site';e[14].v0='13';e[15]=new Object();e[15].type='VectorObject';e[15].v0='1142';e[15].v1='483.00000000000006';e[16]=new Object();e[16].type='Point';e[16].v0='15';e[17]=new Object();e[17].type='StringObject';e[17].v0='3';e[18]=new Object();e[18].type='Text';e[18].v0='17';e[18].v1='16';e[19]=new Object();e[19].type='Site';e[19].v0='18';e[20]=new Object();e[20].type='StringObject';e[20].v0='4';e[21]=new Object();e[21].type='VectorObject';e[21].v0='1080';e[21].v1='340';e[22]=new Object();e[22].type='Point';e[22].v0='21';e[23]=new Object();e[23].type='Text';e[23].v0='20';e[23].v1='22';e[24]=new Object();e[24].type='Site';e[24].v0='23';e[25]=new Object();e[25].type='VectorObject';e[25].v0='1218';e[25].v1='400';e[26]=new Object();e[26].type='Point';e[26].v0='25';e[27]=new Object();e[27].type='StringObject';e[27].v0='5';e[28]=new Object();e[28].type='Text';e[28].v0='27';e[28].v1='26';e[29]=new Object();e[29].type='Site';e[29].v0='28';e[30]=new Object();e[30].type='VectorObject';e[30].v0='1256';e[30].v1='566';e[31]=new Object();e[31].type='Point';e[31].v0='30';e[32]=new Object();e[32].type='StringObject';e[32].v0='6';e[33]=new Object();e[33].type='Text';e[33].v0='32';e[33].v1='31';e[34]=new Object();e[34].type='Site';e[34].v0='33';e[35]=new Object();e[35].type='VectorObject';e[35].v0='1510';e[35].v1='715';e[36]=new Object();e[36].type='Point';e[36].v0='35';e[37]=new Object();e[37].type='StringObject';e[37].v0='16';e[38]=new Object();e[38].type='Text';e[38].v0='37';e[38].v1='36';e[39]=new Object();e[39].type='Site';e[39].v0='38';e[40]=new Object();e[40].type='VectorObject';e[40].v0='1871';e[40].v1='962';e[41]=new Object();e[41].type='Point';e[41].v0='40';e[42]=new Object();e[42].type='StringObject';e[42].v0='17';e[43]=new Object();e[43].type='Text';e[43].v0='42';e[43].v1='41';e[44]=new Object();e[44].type='Site';e[44].v0='43';e[45]=new Object();e[45].type='VectorObject';e[45].v0='1500';e[45].v1='960.0000000000001';e[46]=new Object();e[46].type='Point';e[46].v0='45';e[47]=new Object();e[47].type='StringObject';e[47].v0='8';e[48]=new Object();e[48].type='Text';e[48].v0='47';e[48].v1='46';e[49]=new Object();e[49].type='Site';e[49].v0='48';e[50]=new Object();e[50].type='VectorObject';e[50].v0='1293';e[50].v1='1033';e[51]=new Object();e[51].type='Point';e[51].v0='50';e[52]=new Object();e[52].type='StringObject';e[52].v0='9';e[53]=new Object();e[53].type='Text';e[53].v0='52';e[53].v1='51';e[54]=new Object();e[54].type='Site';e[54].v0='53';e[55]=new Object();e[55].type='VectorObject';e[55].v0='1173';e[55].v1='845';e[56]=new Object();e[56].type='Point';e[56].v0='55';e[57]=new Object();e[57].type='StringObject';e[57].v0='10';e[58]=new Object();e[58].type='Text';e[58].v0='57';e[58].v1='56';e[59]=new Object();e[59].type='Site';e[59].v0='58';e[60]=new Object();e[60].type='StringObject';e[60].v0='12';e[61]=new Object();e[61].type='VectorObject';e[61].v0='717';e[61].v1='979.0000000000001';e[62]=new Object();e[62].type='Point';e[62].v0='61';e[63]=new Object();e[63].type='Text';e[63].v0='60';e[63].v1='62';e[64]=new Object();e[64].type='Site';e[64].v0='63';e[65]=new Object();e[65].type='VectorObject';e[65].v0='887';e[65].v1='316';e[66]=new Object();e[66].type='Point';e[66].v0='65';e[67]=new Object();e[67].type='StringObject';e[67].v0='14';e[68]=new Object();e[68].type='Text';e[68].v0='67';e[68].v1='66';e[69]=new Object();e[69].type='Site';e[69].v0='68';e[70]=new Object();e[70].type='VectorObject';e[70].v0='1027';e[70].v1='758';e[71]=new Object();e[71].type='Point';e[71].v0='70';e[72]=new Object();e[72].type='StringObject';e[72].v0='15';e[73]=new Object();e[73].type='Text';e[73].v0='72';e[73].v1='71';e[74]=new Object();e[74].type='Site';e[74].v0='73';e[75]=new Object();e[75].type='VectorObject';e[75].v0='1305';e[75].v1='1342';e[76]=new Object();e[76].type='Point';e[76].v0='75';e[77]=new Object();e[77].type='StringObject';e[77].v0='18';e[78]=new Object();e[78].type='Text';e[78].v0='77';e[78].v1='76';e[79]=new Object();e[79].type='Site';e[79].v0='78';e[80]=new Object();e[80].type='VectorObject';e[80].v0='822.9999999999999';e[80].v1='1368';e[81]=new Object();e[81].type='Point';e[81].v0='80';e[82]=new Object();e[82].type='StringObject';e[82].v0='19';e[83]=new Object();e[83].type='Text';e[83].v0='82';e[83].v1='81';e[84]=new Object();e[84].type='Site';e[84].v0='83';e[85]=new Object();e[85].type='Line';e[85].v0='1';e[85].v1='6';e[86]=new Object();e[86].type='Line';e[86].v0='6';e[86].v1='11';e[87]=new Object();e[87].type='Line';e[87].v0='11';e[87].v1='16';e[88]=new Object();e[88].type='Line';e[88].v0='16';e[88].v1='22';e[89]=new Object();e[89].type='Line';e[89].v0='22';e[89].v1='26';e[90]=new Object();e[90].type='Line';e[90].v0='26';e[90].v1='31';e[91]=new Object();e[91].type='Line';e[91].v0='46';e[91].v1='51';e[92]=new Object();e[92].type='Line';e[92].v0='51';e[92].v1='56';e[93]=new Object();e[93].type='Line';e[93].v0='66';e[93].v1='71';e[94]=new Object();e[94].type='Line';e[94].v0='41';e[94].v1='76';e[95]=new Object();e[95].type='Line';e[95].v0='76';e[95].v1='81';e[96]=new Object();e[96].type='StringObject';e[96].v0='7';e[97]=new Object();e[97].type='VectorObject';e[97].v0='1606';e[97].v1='648';e[98]=new Object();e[98].type='Point';e[98].v0='97';e[99]=new Object();e[99].type='Text';e[99].v0='96';e[99].v1='98';e[100]=new Object();e[100].type='Site';e[100].v0='99';e[101]=new Object();e[101].type='Line';e[101].v0='31';e[101].v1='98';e[102]=new Object();e[102].type='Line';e[102].v0='98';e[102].v1='46';e[103]=new Object();e[103].type='Line';e[103].v0='71';e[103].v1='36';e[104]=new Object();e[104].type='Line';e[104].v0='36';e[104].v1='41';e[105]=new Object();e[105].type='VectorObject';e[105].v0='520';e[105].v1='1006';e[106]=new Object();e[106].type='Point';e[106].v0='105';e[107]=new Object();e[107].type='StringObject';e[107].v0='13';e[108]=new Object();e[108].type='Text';e[108].v0='107';e[108].v1='106';e[109]=new Object();e[109].type='Site';e[109].v0='108';e[110]=new Object();e[110].type='Line';e[110].v0='62';e[110].v1='106';e[111]=new Object();e[111].type='Line';e[111].v0='106';e[111].v1='66';e[112]=new Object();e[112].type='StringObject';e[112].v0='11';e[113]=new Object();e[113].type='VectorObject';e[113].v0='827';e[113].v1='849';e[114]=new Object();e[114].type='Point';e[114].v0='113';e[115]=new Object();e[115].type='Text';e[115].v0='112';e[115].v1='114';e[116]=new Object();e[116].type='Site';e[116].v0='115';e[117]=new Object();e[117].type='Line';e[117].v0='56';e[117].v1='114';e[118]=new Object();e[118].type='Line';e[118].v0='114';e[118].v1='62';e[119]=new Object();e[119].type='VectorObject';e[119].v0='754';e[119].v1='1224';e[120]=new Object();e[120].type='Point';e[120].v0='119';e[121]=new Object();e[121].type='Line';e[121].v0='81';e[121].v1='120';e[122]=new Object();e[122].type='StringObject';e[122].v0='';e[123]=new Object();e[123].type='Text';e[123].v0='122';e[123].v1='120';e[124]=new Object();e[124].type='Site';e[124].v0='123';"/></label>
<input type="button" onclick="loadData(event)" value="Load"/><br>
Firefox Users: Note that the course is automatically saved when the browser window closes.
	
	<br>
	<br>
</div>


<div class="noprint">
<b>4. Print or Export</b><br>
<input type="button" onclick="zoomAndPrint(event)" value="Print"/>
<input type="button" onclick="exportAsPNG(event)" value="Export PNG"/><br>
Firefox Users: Right click on the drawing surface and select "Save Image As..." option.
	
	<br>
	<br>
</div>



<div class="noprint">
	<div id="trace"></div>
</div>


<div class="noprint">
<b>Previous Courses:</b><br>
<a href="2010-Aug-25-Introductory.html">2010-Aug-25 Introductory Course at Queen Elizabeth Park</a><br>
<a href="2010-Aug-25-Intermediate.html">2010-Aug-25 Intermediate Course at Queen Elizabeth Park</a><br>
<a href="2010-Dec-1.html">2010-Dec-1 Universal Course at Stanley Park</a><br>
<a href="2011-Jan-26.html">2011-Jan-26 Universal Course Downtown Vancouver</a><br>
<br>
</div>

<div class="noprint">
<b>Known Issues:</b><br>
Can be picky joining lines to points<br>
Stop and Finish location cannot be in the same location<br>
Too many updates sent during data import<br>
Performance issues<br>
drawing outside bounds bug<br>
arc drawing bug<br>
Background image: import progress needed<br>
Refresh issues while dragging objects<br>
Thomas box missing<br>
Butterfly course broken<br>
free form lines not implemented<br>
line style function missing<br>
server saving/loading missing<br>
Text size, colour, arrangement features missing<br>
variable zoom missing<br>
tagging function missing<br>
collaborative editing function missing<br>
Colour reproduction issues<br>
Resolution issues: making the line width/site size appropriate<br>
Support for multiple course routes<br>
Individually coded maps for timing<br>
</div>


</body>

</html>